package com.textanalyzer.util;

import java.util.List;
import java.util.StringTokenizer;
import java.util.Vector;

import net.zemberek.erisim.Zemberek;
import net.zemberek.tr.yapi.TurkiyeTurkcesi;
import net.zemberek.yapi.Kelime;
import net.zemberek.yapi.KelimeTipi;
import net.zemberek.yapi.Kok;
import net.zemberek.yapi.ek.Ek;

/**
 * The Sentence Worker Class which has utility functions for data pre-processing
 * for data mining.
 * 
 */
public class SentenceWorker {
	/**
	 * The negative suffix.
	 */
	private static final String SUFFIX_NEGATIVE = "FIIL_OLUMSUZLUK_";

	/**
	 * Return new instance of {@link SentenceWorker}
	 */
	public SentenceWorker() {
		// create new zemberek object.
		zemberek = new Zemberek(new TurkiyeTurkcesi());
	}

	/**
	 * The sentence delimiters.
	 */
	private static String sentenceDelimiters = ".,:;'\\\"()?! ";
	/**
	 * Language helper...
	 */
	private Zemberek zemberek;;

	/**
	 * Return words of given sentence with out any inference.
	 * 
	 * @param sentence
	 *            {@link String}
	 * @return Array of Words.
	 */
	public List<String> getPureWord(String sentence) {
		// create String tokenizer...
		StringTokenizer tokenizer = new StringTokenizer(sentence,
				sentenceDelimiters);
		// initiate list of word..
		List<String> words = new Vector<String>();
		while (tokenizer.hasMoreElements()) {
			// add word to word list.
			String word = tokenizer.nextToken();
			// check the word...
			if (isProperWord(word))
				words.add(word);
		}
		return words;
	}

	/**
	 * Return the given string is word or not.
	 * 
	 * @param str
	 *            {@link String}
	 * @return String or not.
	 */
	private boolean isProperWord(String str) {
		return zemberek.kelimeDenetle(str);
	}

	/**
	 * The method reduct the word gramatically.
	 * 
	 * @param word
	 *            {@link String}
	 * @return reducted word.
	 */
	public String reductWord(String word) {
		// resolve the word.
		String reductedWord = "";
		Kelime[] kelimes = zemberek.kelimeCozumle(word);
		for (Kelime kelime : kelimes) {
			Kok kok = kelime.kok();
			reductedWord = kok.icerik();
			if (kok.tip().equals(KelimeTipi.FIIL)) {
				List<Ek> ekler = kelime.ekler();
				for (Ek ek : ekler) {
					if (isNegativeSuffix(ek)) {

						reductedWord = addSuffix(kok, ek);
						break;
					}
				}
				reductedWord = reductedWord + getMastar(reductedWord);
			}

		}
		return reductedWord;
	}

	/**
	 * This method is the method which add given ek to given kok.
	 * 
	 * @param kok
	 *            {@link Kok}
	 * @param ek
	 *            {@link Ek}
	 * @return
	 */
	private String addSuffix(Kok kok, Ek ek) {
		String verb;
		String ekStr = ek.toString();
		verb = kok.icerik()
				+ ekStr.substring(SUFFIX_NEGATIVE.length()).toLowerCase();
		return verb;
	}

	/**
	 * Return Ek is Negative suffix or not.
	 * 
	 * @param ek
	 *            {@link Ek}
	 * @return Ek is negative suffix or not.
	 * */
	private boolean isNegativeSuffix(Ek ek) {
		return ek.ad().contains(SUFFIX_NEGATIVE);
	}

	/**
	 * Return mastar suffix of given verb.
	 * 
	 * @param verb
	 *            {@link String}
	 * @return mastar suffix
	 */
	public String getMastar(String verb) {
		if (isInce(verb))
			return "mek";
		else
			return "mak";
	}

	/**
	 * Return given verb is ince or not.
	 * 
	 * @param verb
	 *            {@link String}
	 * @return verb is ince or not.
	 */
	private boolean isInce(String verb) {
		// ince char sequences.
		String[] ince = { "e", "i", "ö", "ü" };
		boolean isInce = false;
		for (String harf : ince) {

			if (verb.substring(verb.length() - 2).contains(harf)) {
				isInce = true;
				break;
			}

		}
		return isInce;
	}

	/**
	 * Return reducted sentence
	 * 
	 * @param sentence
	 *            {@link String} of Sentence.
	 * @return {@link String}Reducted Sentence
	 */
	public String reductSentence(String sentence) {
		String reductedSentence = "";
		// get words...
		List<String> words = this.getPureWord(sentence);

		for (String word : words) {
			if (reductedSentence.equals(""))
				reductedSentence = this.reductWord(word);
			else
				reductedSentence = reductedSentence + " "
						+ this.reductWord(word);
		}
		return reductedSentence;
	}
}
